// 二、Symbol

// 1.基础
const s1 = Symbol()
const s2 = Symbol()
// console.log(s1===s2);

const s3 = Symbol(123)
// console.log(s3);
const s4 = Symbol('lp')
// console.log(s4.toString());

// 2.作为属性名
let prop = 'name'
const info = {
  // name:'lp',
  [`my${prop}is`]: 'lp'
}
// console.log(info);

const s5 = Symbol('name')
const info2 = {
  [s5]: 'jb',
  age: 18
}
// console.log(info2);

info2[s5] = 'aaaa'
// console.log(info2);

// 3.属性名遍历
// 下面四种方法都获取不到
// for (const key in info2) {
//   console.log(key);
// }
// console.log(Object.keys(info2));
// console.log(Object.getOwnPropertyNames(info2));
// console.log(JSON.stringify(info2));

// 下面可以
// console.log(Object.getOwnPropertySymbols(info2));
// console.log(Reflect.ownKeys(info2));

// 4.两个静态方法：Symbol.for()和Symbol.keyFor()
// Symbol.for 全局搜索有没有这个字符串创建的值
const s6 = Symbol('lp')
const s7 = Symbol('lp')

const s8 = Symbol.for('lp')
const s9 = Symbol.for('lp')
// console.log(s8===s9);

// Symbol.keyFor() 返回全局注册的标识

// console.log(Symbol.keyFor(s8));
// 5. 11个内置symbol值

// 5.1 Symbol.hasInstance
// instanceof
const obj1 = {
  [Symbol.hasInstance](otherObj) {
    console.log(otherObj);
  }
}
// console.log({
//   a:'a'
// } instanceof <any>obj1);

// 5.2 Symbol.isConcatSpreadable 是否被扁平化

// concat
let arr = [1, 2]
// console.log([].concat(arr,[3,4]));
arr[Symbol.isConcatSpreadable] = false
// console.log([].concat(arr,[3,4]));

// 5.3 Symbol.species 指定创建衍生对象的构造函数

class C extends Array {
  constructor(...args) {
    super(...args)
  }
  static get [Symbol.species]() {
    return Array
  }
  getName() {
    return 'lp'
  }
}
const c = new C(1, 2, 3)
const a = c.map(item => item + 1)
// console.log(a);
// console.log(a instanceof C);
// console.log(a instanceof Array);

// 5.4 Symbol.match 
let obj3 = {
  [Symbol.match](string) {
    console.log('match', string.length);
  },
  [Symbol.split](string) {
    console.log('split', string.length);
  }
}
// 'abcde'.match(<RegExp>obj3)
// 5.5 Symbol.replace
// 5.6 Symbol.search
// 5.7 Symbol.split
// 'abcde'.split(<RegExp>obj3)

// 5.8 Symbol.iterator 数组

// 5.9 Symbol.toPrimitive 对象被转化成原始类型值
let obj4: unknown = {
  [Symbol.toPrimitive](type) {
    console.log(type);
  }
}
// const res = (obj4 as number)++

// const res  = `abc${obj4}`  //default

// 5.10 Symbol.toStringTag 当在对象上调用toString方法时，调用

let obj5 = {
  // [Symbol.toStringTag]:'lp'
  get [Symbol.toStringTag](){
    return 'lp'
  }
}
// console.log(obj5.toString());

// 5.11 Symbol.unscopables 和with有关

let obj6 = {
  a:'a',
  b:'b'
}
// console.log(Array.prototype[Symbol.unscopables]);
